﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

using Google.GData.AccessControl;
using Google.GData.Calendar;
using Google.GData.Client;
using Google.GData.Extensions;
using GCalendar;
using System.IO;

using System.Windows.Forms;

namespace GoogleLogger
{
    class Program
    {
        public static int key = 129;
        static CalendarService GCalendarService;
        private ManagedWinapi.Hotkey hotkey;

        static void Main(string[] args)
        {
            string msg = string.Empty;
            bool bBackupcall = false;
            bool bUseGUI = false;
            bUseGUI = true;

            if (args.Length == 1)
            {
                if (args[0] == "help" || args[0] == "h" || args[0] == "?")
                {
                    msg = "There are following commands available: " + Environment.NewLine +
                        "1. help or h or ?" + Environment.NewLine +
                        "  [GoogleLogger.exe help] It will display help contents" + Environment.NewLine +
                        "2. reset" + Environment.NewLine +
                        "  [GoogleLogger.exe reset] To reset user credentials" + Environment.NewLine +
                        "3. CalendarName Event" + Environment.NewLine +
                        "  [GoogleLogger.exe CalendarName Event]To log an event" + Environment.NewLine +
                        "3. backup" + Environment.NewLine +
                        "  [GoogleLogger.exe backup] To backup all calendars" + Environment.NewLine;

                }
                else if (args[0].ToLower() == "reset")
                {
                    XmlConfig.userInfo _User1;
                    _User1.userName = "";
                    _User1.userPassword = "";
                    _User1.SavePassWord = true;
                    XmlConfig.SaveUserInfo(_User1);
                    msg = "User credentials have been removed";
                }
                else if (args[0].ToLower().Trim() == "backup")
                {
                    bBackupcall = true;
                }

                if (bBackupcall == false)
                {
                    if (msg.Length == 0)
                        msg = "No Event details entered";
                    if (bUseGUI)
                    {
                        System.Windows.Forms.MessageBox.Show(msg, msg, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    }
                    else
                    {
                        MyConsole Con = new MyConsole();
                        Con.WriteLine(msg);
                        Con.ReadLine();
                    }
                    return ;
                }
            }

            if (!DetectNet.detectDNS())
            {
                msg = "No network connection found.\nPlease connect to Internet then try again.";
                API.ShowMessage(0, msg, "No network connection found", 20);
                return;
            }
            if (args.Length < 2 && bBackupcall == false)
            {
                msg = "Not Enough Arguments supplied.\nMinimum two Arguments should be given as below:\n1: Calendar Name\n2: Event text to be added";
                API.ShowMessage(0, msg, "Not Enough Arguments supplied", 0);
                return;
            }

            string calName = args[0];
            string EventName = "";
            if (!bBackupcall)
               EventName = args[1];
            if (args.Length > 2)
            {
                for (int x = 2; x < args.Length; x++)
                {
                    EventName = EventName + " " + args[x];
                }
            }

            try
            {
                GCalendarService = new CalendarService("GoogleLogger");
                bool InputStatus = false;
                XmlConfig.userInfo _User;
                _User = XmlConfig.GetUserInfo();
                string strPass = _User.userPassword;
                string strUserName = _User.userName;


                if (strUserName == "" || strUserName == null || strPass == "" || strPass == null)
                {
                    InputStatus = true;
                    
                    if (strUserName == "" || strUserName == null)
                    {
                        if (bUseGUI)
                        {
                            UserCred uc = new UserCred();
                            uc.GetUserData(out _User);
                            strPass = _User.userPassword;
                            strUserName = _User.userName;
                            uc.Close();
                            uc.Dispose();
                        }   
                        else
                        {
                            MyConsole Con = new MyConsole();
                            int count = 0;
                            while (count == 0)
                            {
                                Con.WriteLine("Enter User Name:");
                                strUserName = Con.ReadLine();
                                count = strUserName.IndexOf('\r');
                            }
                            strUserName = strUserName.Substring(0, count);
                            count = 0;
                            while (count == 0)
                            {
                                Con.WriteLine("Enter Password for " + strUserName + ":");
                                strPass = Con.ReadLine();
                                count = strPass.IndexOf('\r');
                            }

                            strPass = strPass.Substring(0, count);
                            Con.Dispose();
                        }

                        strPass = EncryptDecrypt(strPass);                        
                    }
                    else if (strPass == "" || strPass == null)
                    {
                        if (bUseGUI)
                        {
                            UserCred uc = new UserCred();
                            uc.GetUserPass(out _User, strUserName);
                            strPass = _User.userPassword;
                            strUserName = _User.userName;
                            uc.Close();
                            uc.Dispose();
                        }
                        else
                        {
                            MyConsole Con = new MyConsole();
                            Con.WriteLine("Enter Password for " + strUserName + ":");
                            strPass = Con.ReadLine();
                            Con.Dispose();
                        }
                        strPass = EncryptDecrypt(strPass);                        
                    }
                }

                strPass = EncryptDecrypt(strPass);

                if (GCalendar.GCalendar.UserAuthen(strUserName, strPass))
                {
                    GCalendar.GCalendar gcal = new GCalendar.GCalendar();
                    string strPassEncrypted = EncryptDecrypt(strPass);
                    _User.userPassword = strPassEncrypted;
                    _User.userName = strUserName;
                    _User.SavePassWord = true;
                    if (InputStatus == true)
                        XmlConfig.SaveUserInfo(_User);

                    string[] gcalList = gcal.CalendarList();
                    if (!bBackupcall && !gcalList.Contains(calName))
                    {
                        msg = string.Format("Calendar {0} not found in the collection of calendars", calName);
                        API.ShowMessage(0, msg, "Item not found", 0);
                        return;
                    }
                    if (bBackupcall)
                    {
                        MyConsole newcon = new MyConsole();
                        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(Environment.CurrentDirectory + @"\Temp\");
                        if (!dir.Exists)
                            dir.Create();
                        System.IO.DirectoryInfo dirBackup = new System.IO.DirectoryInfo(Environment.CurrentDirectory + @"\Backup\");
                        if (!dirBackup.Exists)
                            dirBackup.Create();
                        foreach (FileInfo fInfo in dir.GetFiles())
                        {
                            if (fInfo.Extension == ".zip")
                            {
                                fInfo.MoveTo(Environment.CurrentDirectory + @"\Backup\" + fInfo.Name);
                            }
                            else
                                fInfo.Delete();
                        }
                        dir.Delete();
                        if (!dir.Exists)
                            dir.Create();

                        foreach (string cal in gcalList)
                        {
                            BackupCal Cal = new BackupCal();
                            newcon.WriteLine(Environment.NewLine + "----------------" + Environment.NewLine + cal + Environment.NewLine);
                            newcon.WriteLine("----------------");
                            EventEntry[] CalEvent = gcal.GETEnventList(cal);
                            foreach (EventEntry eve in CalEvent)
                            {
                                When w = eve.Times[0];
                                newcon.WriteLine(string.Format("{0}: {1}", eve.Title.Text, w.StartTime.ToString()));
                                Cal.Name = cal;
                                Cal.AddEvent(eve.Title.Text, w.StartTime, w.EndTime);
                            }
                            string filepath = System.IO.Path.Combine(dir.ToString(), Cal.Name + ".xml");
                            System.IO.StreamWriter sw = new System.IO.StreamWriter(System.IO.File.Create(filepath));
                            System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(typeof(BackupCal));
                            xml.Serialize(sw, Cal);
                            sw.Close();                            
                        }
                        //ZipUtil.ZipFiles(dir.ToString(), DateTime.Now.ToString("dd:MM:yyyy HH:mm:ss:ffff"), strPass);
                        string zipname = DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".zip";
                        ZipUtil.ZipFiles(dir.ToString(), zipname, strPass);

                        newcon.ReadLine();
                        return;
                    }
                    else
                    {
                       Event item = new Event(calName, EventName);
                       GCalendar.GCalendar.AddEvent(item.Item, calName);
                    }
                }
                else
                {
                    msg = "Authentication failed for user: " + strUserName;
                    API.ShowMessage(0, msg, "Authentication Failed", 0);
                    return;
                }
            }
            catch (Exception ex)
            {
                API.ShowMessage(0, ex.Message, "Exception Occurred", 0);
                return;

            }
        }

        protected bool OnStartup()
        {
            bool bexe = true;

            if (bexe == true)
                return true;
            hotkey = new ManagedWinapi.Hotkey();
            hotkey.WindowsKey = true;
            hotkey.KeyCode = System.Windows.Forms.Keys.Space;
            hotkey.HotkeyPressed += new EventHandler(hotkey_HotkeyPressed);
            try
            {
                hotkey.Enabled = true;
            }
            catch (ManagedWinapi.HotkeyAlreadyInUseException)
            {
                System.Windows.Forms.MessageBox.Show("Could not register hotkey (already in use).", "Error", MessageBoxButtons.OK , MessageBoxIcon.Error);

            }
            return bexe;
        }

        void hotkey_HotkeyPressed(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        public static string EncryptDecrypt(string textToEncrypt)
        {
            StringBuilder inSb = new StringBuilder(textToEncrypt);
            StringBuilder outSb = new StringBuilder(textToEncrypt.Length);
            char c;
            for (int i = 0; i < textToEncrypt.Length; i++)
            {
                c = inSb[i];
                c = (char)(c ^ key);
                outSb.Append(c);
            }
            return outSb.ToString();
        }
    }


}
